package models

import (
	"GoTime/response"
	"GoTime/utils"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/spf13/cast"
	"xorm.io/builder"
)

type Coach struct {
	Id               int       `xorm:"not null pk autoincr comment('自增主键') INT(11)" json:"id"`
	UserId           int       `xorm:"not null comment('用户id外键关联dts_user中的id')  INT(11)" json:"user_id"`
	SchoolId         int       `xorm:"not null comment('驾校id外键关联dts_school中的自增id')  INT(11)" json:"school_id" from:"school_id"`
	IcId             int       `xorm:"default 0 comment('IC卡id,学员可以没有IC卡也可以拥有多张IC卡，当前为生效IC卡id') INT(11)" json:"ic_id" from:"ic_id"`
	InstitutionCode  string    `xorm:"comment('运管统一编号')  VARCHAR(16)" json:"institution_code" from:"institution_code"`
	FingerId         int       `xorm:"default 0 comment('指纹id，教练员可以拥有多个指纹记录，当前为生效指纹id') INT(11)" json:"finger_id" from:"finger_id"`
	PortraitId       int       `xorm:"default 0 comment('头像id，教练员可以拥有多个头像记录，当前为生效头像id') INT(11)" json:"portrait_id" from:"portrait_id"`
	LicenceNumber    string    `form:"licence_number" xorm:"default '' comment('驾驶证号') VARCHAR(128)" json:"licence_number" from:"licence_number"`
	LicenceGrantDate time.Time `xorm:"comment('驾驶证初领日期 YYYYMMDD') DATE" json:"licence_grant_date" from:"licence_grant_date"`
	OccupationNumber string    `form:"occupation_number" xorm:"default '' comment('教练员职业资格证件号') VARCHAR(128)" json:"occupation_number" from:"occupation_number"`
	OccupationRank   string    `form:"occupation_rank" xorm:"default '1' comment('教练员职业资格等级，1：一级，2：二级，3：三级，4：四级') ENUM('1','2','3','4')" json:"occupation_rank" from:"occupation_rank"`
	DrivingCarType   string    `form:"driving_car_type"  xorm:"default 'C1' comment('准驾车型') ENUM('A1','A2','A3','B1','B2','C1','C2','C3','C4','C5','D','E','F','M','N','P')" json:"driving_car_type" from:"driving_car_type"`
	DrivingCarTypes  string    `form:"driving_car_types"  xorm:"default 'C1' comment('准驾车型')" json:"driving_car_types" from:"driving_car_types"`
	TeachingCarType  string    `form:"teaching_car_type" xorm:"default 'C1' comment('准教车型') ENUM('A1','A2','A3','B1','B2','C1','C2','C3','C4','C5','D','E','F','M','N','P')" json:"teaching_car_type" from:"teaching_car_type"`
	TeachingCarTypes string    `form:"teaching_car_types" xorm:"default 'C1' comment('准教车型')" json:"teaching_car_types" from:"teaching_car_types"`
	EntryDate        time.Time `xorm:"comment('入职日期 YYYYMMDD') DATE" json:"entry_date" from:"entry_date"`
	DepartureDate    time.Time `xorm:"comment('离职日期 YYYYMMDD') DATE" json:"departure_date" from:"departure_date"`
	Status           string    `form:"status" xorm:"default '1' comment('0：在职, 1：离职') ENUM('0','1')" json:"status" from:"status"`
	ApprovalStatus   string    `xorm:"default '0' comment('教练员提交运管审核状态，0:待审核，1:通过审核，2:未通过审核') ENUM('0','1','2')" json:"approval_status" from:"approval_status"`
	RecordStatus     string    `xorm:"not null default '0' comment('备案状态 0:未备案 1:已备案') ENUM('0','1')" json:"record_status" from:"record_status"`
	RecordStatus2    string    `xorm:"not null default '0' comment('濮阳备案状态 0:未备案 1:已备案') ENUM('0','1')" json:"record_status_2" from:"record_status_2"`
	LoginStatus      string    `xorm:"default '0' comment('0：登出状态    1：登录状态') ENUM('0','1')" json:"login_status" from:"login_status"`
	CourseId         int       `xorm:"comment('班级id')  INT(11)" json:"course_id" from:"course_id"`
	FieldId          int64     `xorm:"comment('所属训练场')  INT(11)" json:"field_id" from:"field_id"`
	Starlevel        int       `xorm:"default 0 comment('1-10:1星级，10-20：2星级，:20-30；3星级，依次类推')  INT(11)"`
	Servicetimes     int       `xorm:"default 0 comment('教练的服务次数') INT(11)" json:"servicetimes" from:"servicetimes"`
	Subject          string    `form:"subject" xorm:"comment('1-科一，2-科二,3-科三，4科四') ENUM('1','2','3','4')" json:"subject" from:"subject"`
	CharstandardId   int64     `form:"charstandard_id" xorm:"default 0 comment('缴费班级ID') INT(11)" json:"charstandard_id" from:"charstandard_id"`
	Jsznumber        string    `xorm:"comment('档案编号') VARCHAR(255)" json:"jsznumber" from:"jsznumber"`
	Remark           string    `xorm:"comment('备注') VARCHAR(255)" json:"remark" from:"remark"`
	Isused           string    `xorm:"default '1' comment('0已删除 1在使用') ENUM('0','1')" json:"isused"`
	AddTime          time.Time `xorm:"default 'CURRENT_TIMESTAMP' comment('添加时间') TIMESTAMP" json:"add_time"`
	Clicknum         int       `xorm:"INT(11)" json:"clicknum"`
}

func (c *Coach) GetCoachList(filter builder.Cond, schoolId, pageSize, offset int) (count int64, list []response.CoachListResponse, err error) {
	if err = engine.Table("dts_coach").Alias("c").
		Select("c.id,u.id as user_id,p.image_url,c.school_id,c.institution_code,c.occupation_number,c.status,c.subject,c.login_status,c.approval_status,c.record_status,c.record_status,c.teaching_car_type,c.teaching_car_types,c.entry_date,c.departure_date,c.licence_number,c.licence_grant_date,c.occupation_rank,c.driving_car_type,c.driving_car_types,u.name as Name,u.phone,u.nation,u.address,u.nationality,u.sex,u.id_number,u.id_type,u.district").
		Join("LEFT", []string{"dts_user", "u"}, "c.user_id=u.id").
		Join("LEFT", []string{"dts_portrait", "p"}, "p.id=c.portrait_id").
		Where("c.school_id=? and c.isused=?", schoolId, "1").And(filter).Desc("c.id").Limit(pageSize, offset).Find(&list); err != nil {
		return 0, list, err
	}
	log.Println(err)
	_, err = engine.Table("dts_coach").Alias("c").Select("count(c.id) as count").
		Join("LEFT", []string{"dts_user", "u"}, "c.user_id=u.id").
		Join("LEFT", []string{"dts_portrait", "p"}, "p.id=c.portrait_id").
		Where("c.school_id=? and c.isused=?", schoolId, "1").And(filter).Get(&count)
	if err != nil {
		return count, list, err
	}
	for k, _ := range list {
		list[k].Phone = strings.Replace(list[k].Phone, "c", "", -1)
		list[k].IdNumber = strings.Replace(list[k].IdNumber, "c", "", -1)
	}
	return count, list, nil
}

func (c *Coach) GetCoachById(id interface{}) (coach *Coach, err error) {
	coach = new(Coach)
	_, err = engine.Table("dts_coach").Where("id = ? and isused = ?", id, "1").Get(coach)
	log.Println(err)
	return
}

// GetInstitutionCode 获取运管统一编号
func (c *Coach) GetInstitutionCode(schoolCode string, user *User, photo, finger, province, city string) (coach *Coach, err error) {
	var (
		url    string
		retMap map[string]interface{}
		//req_type int64
	)
	data := map[string]interface{}{
		"inscode":         schoolCode,                                  //培训机构编号
		"name":            user.Name,                                   // 姓名
		"sex":             user.Sex,                                    //性别
		"idcard":          strings.Replace(user.IdNumber, "c", "", -1), //身份证号
		"mobile":          strings.Replace(user.Phone, "c", "", -1),    //手机号码
		"photo":           photo,                                       //照片文件ID
		"drilicence":      c.LicenceNumber,                             //驾驶证号
		"fstdrilicdate":   c.LicenceGrantDate.Format("20060102"),       //驾驶证初领日期
		"occupationlevel": c.OccupationRank,                            //职业资格等级
		"employstatus":    c.Status,                                    //供职状态
		"hiredate":        c.EntryDate.Format("20060102"),              //入职日期
		"address":         user.Address,
		"fingerprint":     finger,
		"occupationno":    c.OccupationNumber,
	}
	if province == "420000" {
		data["teachpermitted"] = c.TeachingCarTypes
		data["dripermitted"] = c.DrivingCarTypes
	} else {
		data["teachpermitted"] = c.TeachingCarType
		data["dripermitted"] = c.DrivingCarType
	}
	//请求获取加密地址
	if url, err = utils.GetSignURL("coach", data, 1, province, city); err != nil {
		return c, err
	}
	param, err := json.Marshal(data)
	if err != nil {
		fmt.Println("json.Marshal failed:", err)
		return
	}
	var api_log ApiLog
	api_log.Url = url
	api_log.Param = string(param)
	api_log.Method = "POST"
	api_log.Time = time.Now()
	//请求运管
	if retMap, err = utils.APIReq(url, data, "POST"); err != nil {
		result, _ := json.Marshal(retMap)
		api_log.Result = string(result)
		api_log.Add()
		return c, err
	}
	result, _ := json.Marshal(retMap)
	api_log.Result = string(result)
	api_log.Add()
	errorcode, _ := cast.ToInt64E(retMap["errorcode"])
	if errorcode != 0 {
		return c, errors.New(retMap["message"].(string))
	}
	if md, ok := retMap["data"].(map[string]interface{}); ok {
		c.InstitutionCode = fmt.Sprint(md["coachnum"])
		return c, nil
	}

	//武汉市单独请求
	//if city == "420100" {
	//	// req_type = 3
	//	if err := utils.WuhanSignReq("coach", data, 3, province, city); err != nil {
	//		return c, err
	//	}
	//}
	return c, errors.New("获取教练编号失败")
}

func (c *Coach) RecordCoach(institutionCode string, user *User, province string, city string, photo string, fingerCode string, imageUrl string) (err error) {
	fmt.Print(institutionCode, "institution_code")
	data := map[string]interface{}{
		"inscode":       institutionCode,                             //培训机构编号
		"coachnum":      c.InstitutionCode,                           //教练员编号
		"name":          user.Name,                                   //姓名
		"sex":           user.Sex,                                    //性别
		"idcard":        strings.Replace(user.IdNumber, "c", "", -1), //身份证号
		"mobile":        strings.Replace(user.Phone, "c", "", -1),    //手机号码
		"photo":         photo,                                       //照片文件ID
		"drilicence":    c.LicenceNumber,                             //驾驶证号
		"fstdrilicdate": c.LicenceGrantDate.Format("20060102"),       //驾驶证初领日期
		"employstatus":  c.Status,                                    //供职状态0:在职1:离职
		"hiredate":      c.EntryDate.Format("20060102"),              //入职日期
		//"leavedate":       leavedate,                                   //离职日期
	}
	if province == "420000" {
		data["teachpermitted"] = c.TeachingCarTypes
		data["dripermitted"] = c.DrivingCarTypes
	} else {
		data["teachpermitted"] = c.TeachingCarType
		data["dripermitted"] = c.DrivingCarType
	}

	var (
		apiUrl  string
		retMap  map[string]interface{}
		reqType int64
	)
	reqType = 2
	if c.Subject == "1" {
		data["teachtype"] = "0"
	} else if c.Subject == "2" {
		data["teachtype"] = "1"
	} else if c.Subject == "3" {
		data["teachtype"] = "2"
	} else if c.Subject == "4" {
		data["teachtype"] = "3"
	} else if c.Subject == "5" {
		data["teachtype"] = "4"
	}
	if c.Status == "1" {
		data["leavedate"] = c.DepartureDate.Format("20060102")
	}
	if data["photo"], err = utils.FileId(imageUrl, "coachimg", reqType, province, city); err != nil {
		return err
	}
	//请求获取加密地址
	if province != "520000" {
		data["address"] = user.Address
		data["fingerprint"] = fingerCode
		data["occupationno"] = c.OccupationNumber
	}
	if apiUrl, err = utils.GetSignURL("coach", data, reqType, province, city); err != nil {
		return err
	}
	param, err := json.Marshal(data)
	if err != nil {
		fmt.Println("json.Marshal failed:", err)
		return
	}
	var api_log ApiLog
	api_log.Url = apiUrl
	api_log.Param = string(param)
	api_log.Method = "POST"
	api_log.Time = time.Now()
	//请求运管
	if retMap, err = utils.APIReq(apiUrl, data, "POST"); err != nil {
		result, _ := json.Marshal(retMap)
		api_log.Result = string(result)
		api_log.Add()
		return err
	}
	result, _ := json.Marshal(retMap)
	api_log.Result = string(result)
	api_log.Add()
	fmt.Println(retMap)
	switch retMap["errorcode"].(type) {
	case float64:
		if retMap["errorcode"].(float64) != 0 && !strings.Contains(retMap["message"].(string), "已经备案") {
			return errors.New(retMap["message"].(string))
		}
	case string:
		if retMap["errorcode"].(string) != "0" && !strings.Contains(retMap["message"].(string), "已经备案") {
			return errors.New(retMap["message"].(string))
		}
	}
	if province == "340000" {
		//fmt.Println("是否到此一游")
		//data["photoPath"] = imageUrl
		//data["baTime"] = time.Now().Format("2006-01-02 15:04:05")
		//delete(data, "photo")
		//if resp, err := utils.AnHuiServiceAPIURLRequest("driverBA/add.do", "POST", institutionCode, data); err != nil {
		//	logs.ZapLogs.Error(err.Error(), zap.String("coach", cast.ToString(resp["token"])))
		//	// utils.Logfile("anhuicoach", "log.anhuicoach.log")
		//	// utils.Logfile(err, "log.anhuicoachadd.log")
		//} else {
		//	// fmt.Println(resp, "driverBA/add.do")
		//	logs.ZapLogs.Info("AnHuiServiceAPIURLRequest", zap.String("coach", cast.ToString(resp["token"])))
		//}
	}
	return nil
}

func (c *Coach) GetDeviceCoach(phone string) (ok bool, coach *Coach, err error) {
	ok, err = engine.Table("dts_coach").Alias("c").
		Join("LEFT", []string{"dts_user", "u"}, "c.user_id=u.id").
		Where("u.phone=? and u.type = ? and u.isused = ? and c.isused = ?", phone, "3", "1", "1").
		Get(&coach)
	return ok, coach, err
}

func (c *Coach) Edit(who ...string) (coach *Coach, err error) {
	if _, err = engine.ID(c.Id).Cols(who...).Update(c); err != nil {
		return nil, err
	}
	return c, err
}
